package org.longteng.security.api;

import org.longteng.core.annotation.AuthIgnore;
import org.longteng.core.base.TokenResult;
import org.longteng.security.Constants;
import org.longteng.security.service.JwtTokenService;
import org.longteng.security.vo.AuthorizationUserVo;
import org.longteng.security.vo.AuthorizationVo;
import org.longteng.core.utils.JSONObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

import javax.security.auth.message.AuthException;
import java.util.Optional;
import java.util.concurrent.ExecutorService;

/**
 * 接口身份验证取得token
 * @author hymn.com
 * @date 2022/12/07 10:00:00
 */
@RestController
@Slf4j
public class TokenController {

    @Autowired
    private JwtTokenService jwtTokenService;
    @Autowired
    private ExecutorService executorService;

    /**
     * 用户登录验证取得token
     * @param user 用户帐号
     * @return TokenResult<TokenData>
     */
    @PostMapping("/{user}/api/getToken")
    @AuthIgnore
    public TokenResult getToken(@PathVariable("user") String user
                , @RequestHeader(value = Constants.TOKEN_HEADER_AUTHORIZATION,required = false) String headerAuthJson) {
        log.debug("用户登录验证取得token, user:{},参数：{}", user, headerAuthJson);
        try {
            AuthorizationVo authorizationVo = JSONObjectUtil.parseObject(headerAuthJson, AuthorizationVo.class);
            if (authorizationVo == null) {
                return TokenResult.failed("需求在请求Header提供appId及签名信息.");
            }

            AuthorizationUserVo authUserVo = new AuthorizationUserVo();
            authUserVo.setUser(user);
            authUserVo.setAuthorization(authorizationVo);
            TokenResult.TokenData tokenData = jwtTokenService.buildToken(authUserVo);
            this.insertOlineToken(tokenData);  // 记录在线token 到tokenOnlineCountMap

            return TokenResult.success(tokenData);
        }catch (AuthException e) {
            log.error("用户或appId验证失败.", e);
            return TokenResult.failed(e.getMessage());  // 用户或appId验证失败
        }catch (RuntimeException
                e) {
            log.error("生成token异常.", e);
            return TokenResult.failed("生成token异常.");
        }catch (Exception e) {
            log.error("用户登录验证取得token异常.", e);
            return TokenResult.failed("取得token异常.");
        }

    }

    /**
     * 记录在线token 到tokenOnlineCountMap
     * @param tokenData
     */
    private void insertOlineToken(TokenResult.TokenData tokenData) {
        final String token = Optional.ofNullable(tokenData).orElse(new TokenResult.TokenData()).getToken();
        log.debug("开始线程记录1个在线token.");
        executorService.execute(new Runnable() {
            public void run() {
                jwtTokenService.insertOlineToken(token);
            }
        });
    }

    /**
     * 刷新token,已过期的不能刷新，可先不开放
     * @param token
     * @return
     */
    public TokenResult refreshToken(String token) {
        try {
            TokenResult.TokenData tokenData = jwtTokenService.refreshToken(token);
            return TokenResult.success(tokenData);
        }catch (RuntimeException e) {
            return TokenResult.failed("刷新token异常.");
        }
    }

}
